package org.com.controller;

import io.swagger.annotations.Api;
import org.com.common.R;
import org.com.dto.ProductPurchaseDTO;
import org.com.pojo.*;
import org.com.service.ProductsService;
import org.com.service.ProductImagesService;
import org.com.service.UserBalanceService;
import org.com.service.TransactionsService;
import org.com.service.FarmsService;
import org.com.service.OrdersService;
import org.com.service.UsersService;
import org.com.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashMap;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

@Slf4j
@RestController
@Api(tags = "订单管理")
@RequestMapping("/api/orders")
public class OrdersController {
    
    @Autowired
    private RedisUtil redisUtil;
    
    @Autowired
    private ProductsService productsService;
    
    @Autowired
    private ProductImagesService productImagesService;

    @Autowired
    private UserBalanceService userBalanceService;

    @Autowired
    private TransactionsService transactionsService;

    @Autowired
    private FarmsService farmsService;

    @Autowired
    private OrdersService ordersService;

    @Autowired
    
    private UsersService userService;
    
    private static final String CART_KEY_PREFIX = "cart:";
    private static final String CART_SET_KEY_PREFIX = "cart_keys:";
    private static final int CART_EXPIRE_TIME = 300; // 5分钟过期
    
    /**
     * 获取用户的购物车信息
     * @param request HttpServletRequest
     * @return 购物车中的商品列表
     */
    @GetMapping("/cart")
    public R getCartItems(HttpServletRequest request) {
        // 获取用户ID
        Integer userId = (Integer) request.getSession().getAttribute("userId");
        if (userId == null) {
            return R.error("用户未登录");
        }
        
        try {
            // 获取该用户的购物车key集合
            String cartSetKey = CART_SET_KEY_PREFIX + userId;
            Set<Object> cartKeys = redisUtil.sGet(cartSetKey);
            
            if (cartKeys == null || cartKeys.isEmpty()) {
                return R.success("购物车为空", new ArrayList<>());
            }
            
            // 获取所有购物车项
            List<java.util.Map<String, Object>> cartItems = new ArrayList<>();
            for (Object key : cartKeys) {
                ProductPurchaseDTO item = (ProductPurchaseDTO) redisUtil.get(key.toString());
                if (item != null) {
                    // 获取最新的商品信息
                    R productResult = productsService.getProductDetail(item.getProductId());
                    if (productResult.getSuccess()) {
                        Products product = (Products) ((java.util.Map<String, Object>) productResult.getData()).get("product");
                        if (product != null) {
                            // 更新商品信息
                            item.setProductName(product.getProductName());
                            item.setPrice(java.math.BigDecimal.valueOf(product.getPrice()));
                            
                            // 获取商品主图
                            LambdaQueryWrapper<ProductImages> queryWrapper = new LambdaQueryWrapper<>();
                            queryWrapper.eq(ProductImages::getProductId, product.getProductId())
                                      .eq(ProductImages::getIsPrimary, 1)
                                      .last("LIMIT 1");
                            ProductImages productImage = productImagesService.getOne(queryWrapper);
                            
                            // 构建返回数据
                            java.util.Map<String, Object> cartItemData = new java.util.HashMap<>();
                            cartItemData.put("productId", item.getProductId());
                            cartItemData.put("productName", item.getProductName());
                            cartItemData.put("price", item.getPrice());
                            cartItemData.put("quantity", item.getQuantity());
                            cartItemData.put("farmId", item.getFarmId());
                            cartItemData.put("farmName", item.getFarmName());
                            cartItemData.put("userId", item.getUserId());
                            cartItemData.put("stock", product.getStock());
                            cartItemData.put("productImage", productImage != null ? productImage.getImageUrl() : "https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png");
                            
                            cartItems.add(cartItemData);
                        }
                    }
                } else {
                    // 如果商品不存在，从集合中移除key
                    redisUtil.setRemove(cartSetKey, key);
                }
            }
            
            return R.success("获取购物车信息成功", cartItems);
        } catch (Exception e) {
            log.error("获取购物车信息失败", e);
            return R.error("获取购物车信息失败：" + e.getMessage());
        }
    }
    
    /**
     * 从购物车中移除商品
     * @param productId 商品ID
     * @param request HttpServletRequest
     * @return 操作结果
     */
    @DeleteMapping("/cart/{productId}")
    public R removeFromCart(@PathVariable Integer productId, HttpServletRequest request) {
        // 获取用户ID
        Integer userId = (Integer) request.getSession().getAttribute("userId");
        if (userId == null) {
            return R.error("用户未登录");
        }
        
        try {
            String cartKey = CART_KEY_PREFIX + userId + ":" + productId;
            String cartSetKey = CART_SET_KEY_PREFIX + userId;
            
            // 删除商品数据
            redisUtil.del(cartKey);
            // 从购物车key集合中移除
            redisUtil.setRemove(cartSetKey, cartKey);
            
            return R.success("商品已从购物车移除");
        } catch (Exception e) {
            log.error("移除购物车商品失败", e);
            return R.error("移除购物车商品失败：" + e.getMessage());
        }
    }
    
    /**
     * 清空购物车
     * @param request HttpServletRequest
     * @return 操作结果
     */
    @DeleteMapping("/cart")
    public R clearCart(HttpServletRequest request) {
        // 获取用户ID
        Integer userId = (Integer) request.getSession().getAttribute("userId");
        if (userId == null) {
            return R.error("用户未登录");
        }
        
        try {
            String cartSetKey = CART_SET_KEY_PREFIX + userId;
            Set<Object> cartKeys = redisUtil.sGet(cartSetKey);
            
            if (cartKeys != null && !cartKeys.isEmpty()) {
                // 删除所有商品数据
                for (Object key : cartKeys) {
                    redisUtil.del(key.toString());
                }
                // 清空购物车key集合
                redisUtil.setRemove(cartSetKey, cartKeys.toArray());
            }
            
            return R.success("购物车已清空");
        } catch (Exception e) {
            log.error("清空购物车失败", e);
            return R.error("清空购物车失败：" + e.getMessage());
        }
    }

    /**
     * 购物车结算
     * @param request HttpServletRequest
     * @return 结算结果
     */
    @PostMapping("/cart/checkout")
    @Transactional(rollbackFor = Exception.class)
    public R checkoutCart(HttpServletRequest request) {
        // 获取用户ID
        Integer userId = (Integer) request.getSession().getAttribute("userId");
        log.info("开始购物车结算, 用户ID: {}", userId);
        
        if (userId == null) {
            throw new RuntimeException("用户未登录");
        }
        
        // 获取该用户的购物车key集合
        String cartSetKey = CART_SET_KEY_PREFIX + userId;
        log.info("正在获取购物车信息, cartSetKey: {}", cartSetKey);
        Set<Object> cartKeys = redisUtil.sGet(cartSetKey);
        
        if (cartKeys == null || cartKeys.isEmpty()) {
            throw new RuntimeException("购物车为空");
        }
        log.info("购物车商品数量: {}", cartKeys.size());

        try {
            // 获取用户余额
            log.info("正在获取用户余额信息...");
            UserBalance userBalance = userBalanceService.getOne(
                new LambdaQueryWrapper<UserBalance>().eq(UserBalance::getUserId, userId)
            );
            if (userBalance == null) {
                throw new RuntimeException("未找到用户余额信息");
            }
            log.info("用户当前余额: {}", userBalance.getBalance());

            // 计算总金额并检查库存
            BigDecimal totalAmount = BigDecimal.ZERO;
            Map<Integer, Integer> productQuantities = new HashMap<>(); // 商品ID -> 购买数量
            Map<Integer, Products> productDetails = new HashMap<>(); // 商品ID -> 商品详情
            
            for (Object key : cartKeys) {
                log.info("正在处理购物车商品, key: {}", key);
                ProductPurchaseDTO item = (ProductPurchaseDTO) redisUtil.get(key.toString());
                if (item != null) {
                    log.info("商品信息: ID={}, 名称={}, 数量={}", item.getProductId(), item.getProductName(), item.getQuantity());
                    
                    // 获取最新的商品信息
                    R productResult = productsService.getProductDetail(item.getProductId());
                    if (!productResult.getSuccess()) {
                        throw new RuntimeException("获取商品信息失败：" + item.getProductName());
                    }
                    
                    Map<String, Object> productData = (Map<String, Object>) productResult.getData();
                    Products product = (Products) productData.get("product");
                    
                    if (product == null) {
                        throw new RuntimeException("商品不存在：" + item.getProductName());
                    }
                    log.info("商品当前库存: {}", product.getStock());
                    
                    // 检查库存
                    if (product.getStock() < item.getQuantity()) {
                        throw new RuntimeException("商品库存不足：" + item.getProductName());
                    }
                    
                    // 累加金额
                    BigDecimal itemAmount = BigDecimal.valueOf(product.getPrice()).multiply(BigDecimal.valueOf(item.getQuantity()));
                    totalAmount = totalAmount.add(itemAmount);
                    log.info("商品小计: {}, 累计总额: {}", itemAmount, totalAmount);
                    
                    // 记录商品购买数量和详情
                    productQuantities.put(product.getProductId(), item.getQuantity());
                    productDetails.put(product.getProductId(), product);
                }
            }
            
            // 检查用户余额是否足够
            log.info("检查用户余额是否足够, 所需金额: {}, 当前余额: {}", totalAmount, userBalance.getBalance());
            if (userBalance.getBalance().compareTo(totalAmount) < 0) {
                throw new RuntimeException("余额不足，请先充值");
            }
            
            // 更新用户余额
            log.info("开始更新用户余额...");
            BigDecimal newBalance = userBalance.getBalance().subtract(totalAmount);
            log.info("计算新余额: 当前余额={} - 支付金额={} = 新余额={}", 
                userBalance.getBalance(), totalAmount, newBalance);
            
            userBalance.setBalance(newBalance);
            userBalance.setUpdatedAt(new Date());
            boolean balanceUpdateResult = userBalanceService.updateById(userBalance);
            if (!balanceUpdateResult) {
                throw new RuntimeException("更新用户余额失败");
            }
            log.info("用户余额更新成功, 新余额: {}", newBalance);
            
            // 记录用户支出交易
            log.info("开始记录用户支出交易...");
            Transactions userTransaction = new Transactions();
            userTransaction.setUserId(userId);
            userTransaction.setBalanceId(userBalance.getBalanceId());
            userTransaction.setDelta(totalAmount.negate()); // 使用negate()确保是负数
            userTransaction.setStatus(3); // 支出
            userTransaction.setCreatedAt(new Date());
            boolean userTransactionResult = transactionsService.save(userTransaction);
            if (!userTransactionResult) {
                throw new RuntimeException("记录用户交易失败");
            }
            log.info("用户支出交易记录成功, 交易金额: {}", userTransaction.getDelta());
            
            // 更新商品库存和记录卖家收入
            log.info("开始处理商品库存和卖家收入...");
            for (Map.Entry<Integer, Products> entry : productDetails.entrySet()) {
                Integer productId = entry.getKey();
                Products product = entry.getValue();
                Integer quantity = productQuantities.get(productId);
                log.info("处理商品: ID={}, 名称={}, 数量={}", productId, product.getProductName(), quantity);
                
                // 更新商品库存
                int newStock = product.getStock() - quantity;
                log.info("计算新库存: 当前库存={} - 购买数量={} = 新库存={}", 
                    product.getStock(), quantity, newStock);
                
                product.setStock(newStock);
                product.setUpdatedAt(new Date());
                boolean stockUpdateResult = productsService.updateById(product);
                if (!stockUpdateResult) {
                    throw new RuntimeException("更新商品库存失败：" + product.getProductName());
                }
                log.info("商品库存更新成功, 新库存: {}", newStock);
                
                // 创建订单记录
                log.info("创建订单记录...");
                Orders order = new Orders();
                order.setUserId(userId);
                order.setProductId(productId);
                order.setQuantity(quantity);
                order.setTotalPrice(product.getPrice() * quantity);
                order.setOrderDate(new Date());
                boolean orderResult = ordersService.save(order);
                if (!orderResult) {
                    throw new RuntimeException("创建订单失败：" + product.getProductName());
                }
                log.info("订单创建成功, 订单ID: {}", order.getOrderId());
                
                // 获取卖家余额
                log.info("获取农场信息, 农场ID: {}", product.getFarmId());
                Farms farm = farmsService.getById(product.getFarmId());
                if (farm == null) {
                    throw new RuntimeException("未找到农场信息");
                }
                log.info("农场所有者ID: {}", farm.getUserId());

                log.info("获取卖家余额信息, 卖家ID: {}", farm.getUserId());
                UserBalance sellerBalance = userBalanceService.getOne(
                    new LambdaQueryWrapper<UserBalance>().eq(UserBalance::getUserId, farm.getUserId())
                );
                if (sellerBalance == null) {
                    throw new RuntimeException("未找到卖家余额信息");
                }
                log.info("卖家当前余额: {}", sellerBalance.getBalance());
                
                // 计算卖家收入
                BigDecimal sellerAmount = BigDecimal.valueOf(product.getPrice()).multiply(BigDecimal.valueOf(quantity));
                log.info("卖家收入金额: {}", sellerAmount);
                
                // 更新卖家余额
                BigDecimal newSellerBalance = sellerBalance.getBalance().add(sellerAmount);
                log.info("计算卖家新余额: 当前余额={} + 收入金额={} = 新余额={}", 
                    sellerBalance.getBalance(), sellerAmount, newSellerBalance);
                
                sellerBalance.setBalance(newSellerBalance);
                sellerBalance.setUpdatedAt(new Date());
                boolean sellerBalanceUpdateResult = userBalanceService.updateById(sellerBalance);
                if (!sellerBalanceUpdateResult) {
                    throw new RuntimeException("更新卖家余额失败");
                }
                log.info("卖家余额更新成功, 新余额: {}", newSellerBalance);
                
                // 记录卖家收入交易
                log.info("记录卖家收入交易...");
                Transactions sellerTransaction = new Transactions();
                sellerTransaction.setUserId(farm.getUserId());
                sellerTransaction.setBalanceId(sellerBalance.getBalanceId());
                sellerTransaction.setDelta(sellerAmount); // 确保是正数
                sellerTransaction.setStatus(0); // 收入
                sellerTransaction.setCreatedAt(new Date());
                boolean sellerTransactionResult = transactionsService.save(sellerTransaction);
                if (!sellerTransactionResult) {
                    throw new RuntimeException("记录卖家交易失败");
                }
                log.info("卖家收入交易记录成功, 交易金额: {}", sellerTransaction.getDelta());
            }
            
            // 所有操作成功后，清空购物车
            log.info("开始清空购物车...");
            for (Object key : cartKeys) {
                redisUtil.del(key.toString());
            }
            redisUtil.del(cartSetKey);
            log.info("购物车清空成功");
            
            log.info("购物车结算完成, 总金额: {}", totalAmount);
            return R.success("结算成功", totalAmount.doubleValue());
        } catch (Exception e) {
            log.error("购物车结算失败: {}", e.getMessage(), e);
            throw new RuntimeException("购物车结算失败：" + e.getMessage());
        }
    }

    /**
     * 临时方法：查询用户余额
     */
    @GetMapping("/checkBalance/{userId}")
    public R checkBalance(@PathVariable Integer userId) {
        try {
            UserBalance balance = userBalanceService.getOne(
                new LambdaQueryWrapper<UserBalance>().eq(UserBalance::getUserId, userId)
            );
            if (balance == null) {
                return R.error("未找到用户余额信息");
            }
            return R.success("查询成功", balance);
        } catch (Exception e) {
            log.error("查询用户余额失败", e);
            return R.error("查询失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户订单列表
     */
    @GetMapping("/list")
    public R getUserOrders(HttpServletRequest request) {
        // 获取用户ID
        Integer userId = (Integer) request.getSession().getAttribute("userId");
        if (userId == null) {
            return R.error("用户未登录");
        }

        try {
            // 查询用户的所有订单
            LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Orders::getUserId, userId)
                       .orderByDesc(Orders::getOrderDate);
            List<Orders> orders = ordersService.list(queryWrapper);

            // 获取订单对应的商品信息
            List<Map<String, Object>> orderList = new ArrayList<>();
            for (Orders order : orders) {
                Map<String, Object> orderInfo = new HashMap<>();
                orderInfo.put("orderId", order.getOrderId());
                orderInfo.put("quantity", order.getQuantity());
                orderInfo.put("totalPrice", order.getTotalPrice());
                orderInfo.put("orderDate", order.getOrderDate());

                // 获取商品信息
                R productResult = productsService.getProductDetail(order.getProductId());
                if (productResult.getSuccess()) {
                    Map<String, Object> productData = (Map<String, Object>) productResult.getData();
                    Products product = (Products) productData.get("product");
                    if (product != null) {
                        orderInfo.put("productId", product.getProductId());
                        orderInfo.put("productName", product.getProductName());
                        orderInfo.put("price", product.getPrice());
                        
                        // 获取商品主图
                        LambdaQueryWrapper<ProductImages> imageWrapper = new LambdaQueryWrapper<>();
                        imageWrapper.eq(ProductImages::getProductId, product.getProductId())
                                  .eq(ProductImages::getIsPrimary, 1)
                                  .last("LIMIT 1");
                        ProductImages productImage = productImagesService.getOne(imageWrapper);
                        orderInfo.put("productImage", productImage != null ? 
                            productImage.getImageUrl() : 
                            "https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png");

                        // 获取农场信息
                        Farms farm = farmsService.getById(product.getFarmId());
                        if (farm != null) {
                            orderInfo.put("farmId", farm.getFarmId());
                            orderInfo.put("farmName", farm.getFarmName());
                        }
                    }
                }
                orderList.add(orderInfo);
            }

            return R.success("获取订单列表成功", orderList);
        } catch (Exception e) {
            log.error("获取订单列表失败", e);
            return R.error("获取订单列表失败：" + e.getMessage());
        }
    }

    /**
     * 管理员获取全部订单列表（分页）
     * @param page 页码
     * @param pageSize 每页大小
     * @return 订单列表
     */
    @GetMapping("/admin/list")
    public R getAdminOrders(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        try {
            // 创建分页对象
            Page<Orders> pageInfo = new Page<>(page, pageSize);
            
            // 查询订单列表（按下单时间倒序）
            LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.orderByDesc(Orders::getOrderDate);
            IPage<Orders> ordersPage = ordersService.page(pageInfo, queryWrapper);

            // 获取订单对应的商品信息
            List<Map<String, Object>> orderList = new ArrayList<>();
            for (Orders order : ordersPage.getRecords()) {
                Map<String, Object> orderInfo = new HashMap<>();
                orderInfo.put("orderId", order.getOrderId());
                orderInfo.put("quantity", order.getQuantity());
                orderInfo.put("totalPrice", order.getTotalPrice());
                orderInfo.put("orderDate", order.getOrderDate());

                // 获取买家信息
                Users buyer = userService.getById(order.getUserId());
                if (buyer != null) {
                    orderInfo.put("userName", buyer.getCallName() != null ? buyer.getCallName() : buyer.getUserName());
                }

                // 获取商品信息
                R productResult = productsService.getProductDetail(order.getProductId());
                if (productResult.getSuccess()) {
                    Map<String, Object> productData = (Map<String, Object>) productResult.getData();
                    Products product = (Products) productData.get("product");
                    if (product != null) {
                        orderInfo.put("productId", product.getProductId());
                        orderInfo.put("productName", product.getProductName());
                        orderInfo.put("price", product.getPrice());
                        
                        // 获取商品主图
                        LambdaQueryWrapper<ProductImages> imageWrapper = new LambdaQueryWrapper<>();
                        imageWrapper.eq(ProductImages::getProductId, product.getProductId())
                                  .eq(ProductImages::getIsPrimary, 1)
                                  .last("LIMIT 1");
                        ProductImages productImage = productImagesService.getOne(imageWrapper);
                        orderInfo.put("productImage", productImage != null ? 
                            productImage.getImageUrl() : 
                            "https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png");

                        // 获取农场信息
                        Farms farm = farmsService.getById(product.getFarmId());
                        if (farm != null) {
                            orderInfo.put("farmId", farm.getFarmId());
                            orderInfo.put("farmName", farm.getFarmName());
                        }
                    }
                }
                orderList.add(orderInfo);
            }

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("records", orderList);
            result.put("total", ordersPage.getTotal());
            result.put("size", ordersPage.getSize());
            result.put("current", ordersPage.getCurrent());
            result.put("pages", ordersPage.getPages());

            return R.success("获取订单列表成功", result);
        } catch (Exception e) {
            log.error("获取订单列表失败", e);
            return R.error("获取订单列表失败：" + e.getMessage());
        }
    }
} 